bl_info = {
    "name": "Simple GeoJSON Importer (无坐标转换)",
    "author": "Blender User",
    "version": (1.3, 0),
    "blender": (3.0, 0),  # 兼容Blender 3.0+
    "location": "文件 > 导入 > 简单GeoJSON (.geojson)",
    "description": "导入GeoJSON（支持Feature/FeatureCollection、MultiPoint/MultiLineString/MultiPolygon），不做坐标转换",
    "warning": "",
    "doc_url": "",
    "category": "Import-Export",
}

import bpy
import json
from bpy_extras.io_utils import ImportHelper
from bpy.props import StringProperty, BoolProperty
from bpy.types import Operator

# 读取GeoJSON主函数（兼容Feature/FeatureCollection）
def import_geojson(filepath):
    # 1. 读取GeoJSON文件
    with open(filepath, 'r', encoding='utf-8') as f:
        try:
            geojson_data = json.load(f)
        except json.JSONDecodeError as e:
            print(f"GeoJSON格式错误：{e}")
            return False

    # 2. 验证并处理GeoJSON类型（Feature/FeatureCollection）
    features = []
    geojson_type = geojson_data.get("type")
    if geojson_type == "FeatureCollection":
        features = geojson_data.get("features", [])
    elif geojson_type == "Feature":
        features = [geojson_data]  # 单个Feature转为列表统一处理
    else:
        print(f"不支持的GeoJSON类型：{geojson_type}（仅支持Feature/FeatureCollection）")
        return False

    if not features:
        print("GeoJSON中无有效Feature数据")
        return False

    # 3. 获取/创建专门的集合（用于存放导入的GeoJSON数据）
    collection_name = "GeoJSON_Import"
    collection = bpy.data.collections.get(collection_name)
    if not collection:
        collection = bpy.data.collections.new(collection_name)
        bpy.context.scene.collection.children.link(collection)
    
    # 设为当前集合（后续创建的物体自动放入）
    bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children[collection_name]

    # 4. 遍历所有Feature，统一处理
    for idx, feature in enumerate(features):
        handle_single_feature(feature, idx)

    print(f"GeoJSON导入完成！共导入 {len(features)} 个Feature")
    return True

# 处理单个Feature（统一逻辑，支持所有几何类型）
def handle_single_feature(feature, feature_idx):
    geom = feature.get("geometry")
    if not geom:
        print(f"跳过无几何数据的Feature（索引：{feature_idx}）")
        return

    geom_type = geom.get("type")
    coordinates = geom.get("coordinates", [])
    # 优先使用Feature的name属性，无则用默认名称
    feature_name = feature.get("properties", {}).get("name", f"GeoJSON_{geom_type}_{feature_idx}")

    # 根据几何类型创建对应物体
    if geom_type == "Point":
        create_point_mesh(coordinates, feature_name)
    elif geom_type == "LineString":
        create_line_object(coordinates, feature_name)
    elif geom_type == "Polygon":
        create_polygon_object(coordinates, feature_name)
    elif geom_type == "MultiPoint":
        create_multipoint_object(coordinates, feature_name)
    elif geom_type == "MultiLineString":
        create_multilinestring_object(coordinates, feature_name)
    elif geom_type == "MultiPolygon":
        create_multipolygon_object(coordinates, feature_name)
    else:
        print(f"不支持的几何类型：{geom_type}（Feature索引：{feature_idx}）")

# 纯散点mesh（Point类型，仅保留核心逻辑）
def create_point_mesh(coords, name):
    x, y = coords[:2]
    z = coords[2] if len(coords) >=3 else 0.0

    vertices = [(x, y, z)]  # 单个顶点
    mesh = bpy.data.meshes.new(f"{name}_mesh")
    mesh.from_pydata(vertices, [], [])
    mesh.update()

    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)

# 线物体（LineString）
def create_line_object(coords_list, name):
    vertices = []
    edges = []
    for i, coords in enumerate(coords_list):
        x, y = coords[:2]
        z = coords[2] if len(coords) >=3 else 0.0
        vertices.append((x, y, z))
        if i > 0:
            edges.append((i-1, i))  # 相邻顶点连成边

    mesh = bpy.data.meshes.new(f"{name}_mesh")
    mesh.from_pydata(vertices, edges, [])
    mesh.update()

    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)

# 面物体（Polygon，支持外边界+孔洞）
def create_polygon_object(coords_list, name, sub_idx=None):
    if not coords_list or not coords_list[0]:
        return

    # 处理子多边形命名（MultiPolygon时添加子索引）
    obj_name = f"{name}_Sub_{sub_idx}" if sub_idx is not None else name
    mesh_name = f"{obj_name}_mesh"

    vertices = []
    faces = []
    # 遍历所有环（0：外边界，1+：孔洞）
    for ring_idx, ring in enumerate(coords_list):
        ring_vertices = []
        for coords in ring:
            x, y = coords[:2]
            z = coords[2] if len(coords) >=3 else 0.0
            vertex_idx = len(vertices)
            vertices.append((x, y, z))
            ring_vertices.append(vertex_idx)
        
        # 至少3个顶点才创建面（孔洞面反向顶点顺序）
        if len(ring_vertices) >=3:
            faces.append(tuple(ring_vertices) if ring_idx == 0 else tuple(reversed(ring_vertices)))

    # 创建网格并修复法线
    mesh = bpy.data.meshes.new(mesh_name)
    mesh.from_pydata(vertices, [], faces)
    mesh.update()

    obj = bpy.data.objects.new(obj_name, mesh)
    bpy.context.collection.objects.link(obj)
    bpy.context.view_layer.objects.active = obj
    obj.select_set(True)

    # 统一修复法线
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.normals_make_consistent(inside=False)
    bpy.ops.object.mode_set(mode='OBJECT')

# 新增：MultiPoint（多点，单个mesh包含所有散点）
def create_multipoint_object(coords_list, name):
    """
    MultiPoint：多个散点合并为一个mesh（高效，避免物体过多）
    坐标格式：[[x1,y1,z1], [x2,y2,z2], ...]
    """
    if not coords_list:
        return

    vertices = []
    # 收集所有点的坐标
    for coords in coords_list:
        x, y = coords[:2]
        z = coords[2] if len(coords) >=3 else 0.0
        vertices.append((x, y, z))

    # 创建包含所有散点的mesh（仅顶点，无边无面）
    mesh = bpy.data.meshes.new(f"{name}_mesh")
    mesh.from_pydata(vertices, [], [])
    mesh.update()

    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)

# 新增：MultiLineString（多线串，每个子线串独立物体）
def create_multilinestring_object(coords_list, name):
    """
    MultiLineString：每个子线串创建独立线物体
    坐标格式：[[[x1,y1], [x2,y2]], [[x3,y3], [x4,y4]], ...]
    """
    if not coords_list:
        return

    # 遍历每个子线串
    for sub_idx, sub_line_coords in enumerate(coords_list):
        if not sub_line_coords:
            continue
        # 子线串命名：基础名称 + _Sub_索引
        sub_line_name = f"{name}_Sub_{sub_idx}"
        # 复用LineString的创建逻辑
        create_line_object(sub_line_coords, sub_line_name)

# 保留：MultiPolygon（多面，每个子面独立物体）
def create_multipolygon_object(coords_list, name):
    """
    MultiPolygon：每个子Polygon创建独立面物体
    坐标格式：[[[[x1,y1],...],[孔洞...]], [[子Polygon2],...]]
    """
    for sub_idx, sub_polygon_coords in enumerate(coords_list):
        if not sub_polygon_coords:
            continue
        create_polygon_object(sub_polygon_coords, name, sub_idx=sub_idx)

# Blender导入操作类（移除顶点大小相关选项）
class IMPORT_SCENE_OT_simple_geojson(Operator, ImportHelper):
    bl_idname = "import_scene.simple_geojson"
    bl_label = "导入简单GeoJSON"
    bl_description = "导入GeoJSON（支持Feature/FeatureCollection、MultiPoint/MultiLineString/MultiPolygon），不做坐标转换"
    bl_options = {'REGISTER', 'UNDO'}

    # 文件筛选器
    filename_ext = ".geojson"
    filter_glob: StringProperty(
        default="*.geojson",
        options={'HIDDEN'},
        maxlen=255,
    )

    def execute(self, context):
        success = import_geojson(self.filepath)
        if success:
            self.report({'INFO'}, f"成功导入GeoJSON文件：{self.filepath}")
        else:
            self.report({'ERROR'}, "GeoJSON导入失败！请检查文件格式")
        return {'FINISHED'}

# 注册插件
def menu_func_import(self, context):
    self.layout.operator(IMPORT_SCENE_OT_simple_geojson.bl_idname, text="简单GeoJSON (.geojson)")

def register():
    bpy.utils.register_class(IMPORT_SCENE_OT_simple_geojson)
    bpy.types.TOPBAR_MT_file_import.append(menu_func_import)

def unregister():
    bpy.utils.unregister_class(IMPORT_SCENE_OT_simple_geojson)
    bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)

if __name__ == "__main__":
    register()